package cn.hsa.fqz.task.service.impl;

import cn.hsa.fqz.common.enums.ProcessStatusEnum;
import cn.hsa.fqz.task.dao.*;
import cn.hsa.fqz.task.entity.*;
import cn.hsa.fqz.task.enums.CheckResultEnums;
import cn.hsa.fqz.task.enums.UserCategoryEnums;
import cn.hsa.fqz.task.service.*;
import cn.hsa.fqz.task.service.dto.*;
import cn.hsa.fqz.util.UserRegionUtils;
import cn.hsa.hsaf.core.framework.util.CurrentUser;
import cn.hsa.hsaf.core.framework.util.PageResult;
import cn.hsa.hsaf.core.framework.web.WrapperResponse;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
@Slf4j
public class TTaskMedcClueFeedbackServiceImpl extends ServiceImpl<TTaskMedcClueFeedbackMapper, TTaskMedcClueFeedbackDO>
    implements TTaskMedcClueFeedbackService{

    @Autowired
    private TTaskMedcClueFeedbackMapper tTaskMedcClueFeedbackMapper;

    @Autowired
    private TTaskMapper tTaskMapper;

    @Autowired
    private IDataFluxService dataFluxService;

    @Autowired
    private TTaskSqlExecuteMapper tTaskSqlExecuteMapper;

    @Autowired
    private TTaskMedcClueFeedbackAttachmentMapper tTaskMedcClueFeedbackAttachmentMapper;

    @Autowired
    private RegionService regionService;

    @Autowired
    private TSysFileService fileService;

    @Autowired
    private TSysFileAccessoryService tSysFileAccessoryService;

    @Autowired
    private TTaskMedcClueFeedbackPulishDetailMapper tTaskMedcClueFeedbackPulishDetailMapper;

    @Override
    public List<TTaskMedcClueFeedbackDO> getLists(String sequenceNo) {
        LambdaQueryWrapper<TTaskMedcClueFeedbackDO>
                wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TTaskMedcClueFeedbackDO::getSequenceNo,sequenceNo);
        return this.list(wrapper);
    }

    @Override
    public TTaskMedcClueFeedbackAttachmentDO getAttachmentByFeedbackAndFileNo(String fileNo, Integer feedbackId) {
        LambdaQueryWrapper<TTaskMedcClueFeedbackAttachmentDO>
                wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TTaskMedcClueFeedbackAttachmentDO::getFileNo,fileNo).eq(TTaskMedcClueFeedbackAttachmentDO::getFeedbackId,feedbackId);
        TTaskMedcClueFeedbackAttachmentDO attachmentDO = tTaskMedcClueFeedbackAttachmentMapper.selectOne(wrapper);
        return attachmentDO;
    }

    @Override
    public List<TTaskMedcClueFeedbackDO> getLists(Integer taskId,String medcCode,Integer fxdj) {
        TTask task = tTaskMapper.selectByPrimaryKey(taskId);
        LambdaQueryWrapper<TTaskMedcClueFeedbackDO>
                wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TTaskMedcClueFeedbackDO::getTaskCode,task.getTaskCode()).eq(TTaskMedcClueFeedbackDO::getMedcCode,medcCode).eq(TTaskMedcClueFeedbackDO::getFxdj,fxdj);
        List<TTaskMedcClueFeedbackDO> result = this.list(wrapper);
        for (TTaskMedcClueFeedbackDO feedbackDO:result) {
            feedbackDO.setCheckResultDesc(CheckResultEnums.getDesc(feedbackDO.getCheckResult()));
            LambdaQueryWrapper<TTaskMedcClueFeedbackAttachmentDO>
                    attachmentDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
            attachmentDOLambdaQueryWrapper.eq(TTaskMedcClueFeedbackAttachmentDO::getFeedbackId,feedbackDO.getId());
            List<TTaskMedcClueFeedbackAttachmentDO> attachmentDOS = tTaskMedcClueFeedbackAttachmentMapper.selectList(attachmentDOLambdaQueryWrapper);
            feedbackDO.setAttachmentDOS(attachmentDOS);

            List<TTaskMedcClueFeedbackPulishDetail> pulishDetailsDOS = tTaskMedcClueFeedbackPulishDetailMapper.selectList(feedbackDO.getId());
            feedbackDO.setPulishDetails(pulishDetailsDOS);

        }
        return result;
    }

    /**
     * 是否存在查否的反馈
     * @param create
     * @return
     */
    @Override
    public Boolean isCheckNone(AddMedcFeedbackDTO create,String proviceCode,String cityCode){
        Integer cfCount = tTaskMedcClueFeedbackMapper.selectCountByTaskCodeAndMedcCodeAndCheckResultAndRegionAndFxdj(create.getTaskCode(), create.getMedcCode(),create.getFxdj(),proviceCode,cityCode,CheckResultEnums.NONE.getValue());
        return cfCount>0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(CurrentUser currentUser, AddMedcFeedbackDTO create) {
        //TODO:这里是针对湖北省仙桃、天门、神农架等直管部门的特殊处理
        String[] hubeiPrvs = {"429004","429005","429006","429021"};
        List<String> hubeiPrvLs = new ArrayList<>(Arrays.asList(hubeiPrvs));
        if(Objects.nonNull(create)){
            TTaskMedcClueFeedbackDO feedbackDO = new TTaskMedcClueFeedbackDO();
            feedbackDO.setCheckResult(create.getCheckResult());
            feedbackDO.setCheckNode(create.getCheckNode());
            feedbackDO.setTaskId(create.getTaskId());
            feedbackDO.setTaskCode(create.getTaskCode());
            feedbackDO.setContent(create.getContent());
            feedbackDO.setCreateBy(currentUser.getUserAcctID());
            feedbackDO.setCreateByName(currentUser.getName());
            feedbackDO.setCreateTime(new Date());
            feedbackDO.setPulishNumber(StringUtils.isEmpty(create.getPulishNumber())?"0":create.getPulishNumber());
            feedbackDO.setMedcCode(create.getMedcCode());
            feedbackDO.setMedcName(create.getMedcName());
            feedbackDO.setPulishCost(create.getPulishCost());
            feedbackDO.setViolateCost(create.getViolateCost());
            feedbackDO.setViolateFund(create.getViolateFund());
            feedbackDO.setViolateFinance(create.getViolateFinance());
            feedbackDO.setSequenceNo(create.getSequenceNo());
            feedbackDO.setTitle(create.getTitle());
            feedbackDO.setDealType(create.getDealType());
            feedbackDO.setProviceCode(create.getProviceCode());
            String cityCode = create.getCityCode();
            if(hubeiPrvLs.contains(cityCode)){
                cityCode = cityCode.substring(0, 6);
            }else{
                cityCode = create.getCityCode();
            }
            feedbackDO.setCityCode(cityCode);
            feedbackDO.setPenaltyCost(create.getPenaltyCost());
            feedbackDO.setFxdj(create.getFxdj()==null?1: create.getFxdj());
            this.save(feedbackDO);
            List<String> attachments = create.getAttachments();
            if(CollectionUtil.isNotEmpty(attachments)){
                for (String attachment:attachments) {
                    LambdaQueryWrapper<TSysFileDO>
                            wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(TSysFileDO::getFileNo, attachment);
                    List<TSysFileDO> result = fileService.list(wrapper);
                    if(CollectionUtil.isNotEmpty(result)){
                        TTaskMedcClueFeedbackAttachmentDO attachmentDO = new TTaskMedcClueFeedbackAttachmentDO();
                        attachmentDO.setTaskId(create.getTaskId());
                        attachmentDO.setFeedbackId(feedbackDO.getId());
                        attachmentDO.setFileNo(attachment);
                        attachmentDO.setFileName(result.get(0).getFileName());
                        tTaskMedcClueFeedbackAttachmentMapper.insert(attachmentDO);
                    }
                }
            }
            List<MedcFeedbackPulishDetailDTO> pulishDetailDTOS = create.getPulishDetailDTOS();
            if(CollectionUtil.isNotEmpty(pulishDetailDTOS)){
                for (MedcFeedbackPulishDetailDTO pulishDetailDTO:pulishDetailDTOS) {

                        TTaskMedcClueFeedbackPulishDetail detail = new TTaskMedcClueFeedbackPulishDetail();
                        BeanUtils.copyProperties(pulishDetailDTO,detail);
                        detail.setFeedbackId(feedbackDO.getId());
                        tTaskMedcClueFeedbackPulishDetailMapper.insertSelective(detail);
                    }
                }
        }
        return Boolean.TRUE;
    }

    @Override
    public TTaskMedcClueFeedbackDO detail(Integer feedbackId) {
        return this.getById(feedbackId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WrapperResponse<Boolean> delete(CurrentUser currentUser, Integer feedbackId) {
        TTaskMedcClueFeedbackDO tTaskMedcClueFeedbackDO = tTaskMedcClueFeedbackMapper.selectById(feedbackId);
        TTask task = tTaskMapper.selectByPrimaryKey(tTaskMedcClueFeedbackDO.getTaskId());
        if(task.getResult().equals(ProcessStatusEnum.FINISHED.name())){
            return WrapperResponse.error(-1,"当前任务已经办结，不可删除反馈内容！",null);
        }
        if(currentUser.getUserAcctID().equals(tTaskMedcClueFeedbackDO.getCreateBy())){
            LambdaQueryWrapper<TTaskMedcClueFeedbackAttachmentDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TTaskMedcClueFeedbackAttachmentDO::getFeedbackId,feedbackId);
            /*List<TTaskMedcClueFeedbackAttachmentDO> dos = tTaskMedcClueFeedbackAttachmentMapper.selectList(wrapper);
            String accessoryId =  DigestUtils.md5Hex(tTaskMedcClueFeedbackDO.getTaskCode()+tTaskMedcClueFeedbackDO.getMedcCode());
            if(CollectionUtil.isNotEmpty(dos)){
                for (TTaskMedcClueFeedbackAttachmentDO attachmentDO:dos) {
                    tSysFileAccessoryService.delete(accessoryId, FileType.MED, attachmentDO.getFileNo());
                    tTaskMedcClueFeedbackAttachmentMapper.deleteById(attachmentDO.getId());
                }
            }*/
            tTaskMedcClueFeedbackAttachmentMapper.delete(wrapper);
            tTaskMedcClueFeedbackPulishDetailMapper.deleteByFeedbackId(feedbackId);
            return WrapperResponse.success(this.removeById(feedbackId));
        }else{
            return WrapperResponse.error(-1,"当前反馈内容不是当前用户提交，不可删除！",null);
        }
    }

    @Override
    public List<MedcFeedbackMinDTO> genMinDtosByTaskIdAndMedcCode(Integer taskId,List<Map<String,String>> medcCodes){
        TTask task = tTaskMapper.selectByPrimaryKey(taskId);
        List<MedcFeedbackMinDTO> result = Lists.newArrayList();
        medcCodes.forEach( e -> {
            MedcFeedbackMinDTO dto = new MedcFeedbackMinDTO();
            dto.setTaskId(taskId);
            String medcCode = e.get("medcCode");
            String fxdj = e.get("fxdj");
            dto.setMedcCode(medcCode);
            MedcFeedbackMinDTO minDTO = tTaskMedcClueFeedbackMapper.selectCountByTaskCodeAndFxdjAndMedcCode(fxdj,task.getTaskCode(),medcCode);
            dto.setCountNum(minDTO.getCountNum());
            result.add(dto);
        });
        return result;
    }

    @Override
    public PageResult<MedcFeedbackDetailsDTO> feedbackedPageList(LoginUserDTO loginUserDTO, TaskFeedbackQueryDTO query) {
        String taskName = tTaskMapper.selectByTaskCode(query.getCondition().getTaskCode()).get(0).getTitle();
        if (query.getCondition() == null) {
            return null;
        }
        Date startTime = null, endTime = null;
        if (Objects.nonNull(query.getCondition())) {
            if (!ArrayUtils.isEmpty(query.getCondition().getTimes())) {
                String start = query.getCondition().getTimes()[0];
                String end = query.getCondition().getTimes()[1];

                if (!org.apache.commons.lang.StringUtils.isBlank(start)) {
                    startTime = DateUtil.beginOfDay(DateUtil.parseDate(start));
                }
                if (!org.apache.commons.lang.StringUtils.isBlank(end)) {
                    endTime = DateUtil.beginOfDay(DateUtil.parseDate(end));
                }
            }
        }

        Page<TTaskMedcClueFeedbackDO> page = PageHelper.startPage(query.getPage().getPageNum(), query.getPage().getPageSize());
        List<TTaskMedcClueFeedbackDO> list = tTaskMedcClueFeedbackMapper.getPageFeedbackByCondition(query.getCondition(), startTime, endTime);
        List<MedcFeedbackDetailsDTO> result = transformFeedbackDetails(list,taskName);
        PageResult<MedcFeedbackDetailsDTO> pageResult = new PageResult<>();
        pageResult.setData(result);
        pageResult.setPageNum(page.getPageNum());
        pageResult.setPageSize(page.getPageSize());
        pageResult.setPages(page.getPages());
        pageResult.setRecordCounts((int)page.getTotal());
        return pageResult;
    }

    @Override
    public List<MedcFeedbackDetailsDTO> feedbackedList(LoginUserDTO loginUserDTO, TaskFeedbackQueryDTO query) {
        if (query.getCondition() == null) {
            return null;
        }
        String taskName = tTaskMapper.selectByTaskCode(query.getCondition().getTaskCode()).get(0).getTitle();
        Date startTime = null, endTime = null;
        if (Objects.nonNull(query.getCondition())) {
            if (!ArrayUtils.isEmpty(query.getCondition().getTimes())) {
                String start = query.getCondition().getTimes()[0];
                String end = query.getCondition().getTimes()[1];

                if (!org.apache.commons.lang.StringUtils.isBlank(start)) {
                    startTime = DateUtil.beginOfDay(DateUtil.parseDate(start));
                }
                if (!org.apache.commons.lang.StringUtils.isBlank(end)) {
                    endTime = DateUtil.beginOfDay(DateUtil.parseDate(end));
                }
            }
        }
        List<TTaskMedcClueFeedbackDO> list = tTaskMedcClueFeedbackMapper.getPageFeedbackByCondition(query.getCondition(), startTime, endTime);
        List<MedcFeedbackDetailsDTO> result = transformFeedbackDetails(list,taskName);
        return result;
    }

    private List<MedcFeedbackDetailsDTO> transformFeedbackDetails(List<TTaskMedcClueFeedbackDO> list,String taskName) {
        List<RegionDO> proviceList = regionService.getRegionsBypRegion("999");
        List<RegionDO> cityList = regionService.getAllCitys();
        List<MedcFeedbackDetailsDTO> detailsDTOS = Lists.newArrayList();
        List<Integer> feedbackIds = list.stream().map(TTaskMedcClueFeedbackDO::getId).collect(Collectors.toList());
        LambdaQueryWrapper<TTaskMedcClueFeedbackAttachmentDO>
                wrapper = new LambdaQueryWrapper<>();
        wrapper.in(TTaskMedcClueFeedbackAttachmentDO::getFeedbackId,feedbackIds);
        List<TTaskMedcClueFeedbackAttachmentDO> attachmentDO = tTaskMedcClueFeedbackAttachmentMapper.selectList(wrapper);
        Map<Integer,List<TTaskMedcClueFeedbackAttachmentDO>> attachmentMap = attachmentDO.stream().collect(Collectors.groupingBy(TTaskMedcClueFeedbackAttachmentDO::getFeedbackId));
        for(TTaskMedcClueFeedbackDO feedbackDO : list){
            MedcFeedbackDetailsDTO dto = new MedcFeedbackDetailsDTO();
            dto.setId(feedbackDO.getId());
            BeanUtils.copyProperties(feedbackDO,dto);
            dto.setTaskName(taskName);
            dto.setCheckResultDesc(CheckResultEnums.getDesc(feedbackDO.getCheckResult()));
            dto.setFxdjDesc(transFxdj(feedbackDO.getFxdj()));
            Optional<RegionDO> pop = proviceList.stream().filter(re -> feedbackDO.getProviceCode().equals(String.valueOf(re.getRegion()))).findFirst();
            if(pop.isPresent()){
                dto.setProviceName(pop.get().getProvice());
            }
            if(StringUtils.isNotEmpty(feedbackDO.getCityCode())){
                Optional<RegionDO> cop = cityList.stream().filter(re -> feedbackDO.getCityCode().equals(String.valueOf(re.getRegion()))).findFirst();
                if(cop.isPresent()){
                    dto.setCityName(cop.get().getCity());
                }
            }
            List<TTaskMedcClueFeedbackPulishDetail> pulishDetails = tTaskMedcClueFeedbackPulishDetailMapper.selectList(feedbackDO.getId());
            List<TTaskMedcClueFeedbackAttachmentDO> attachmentDOS = attachmentMap.get(feedbackDO.getId().intValue());
            if(CollectionUtil.isNotEmpty(attachmentDOS)){
                dto.setAttachmentDOS(attachmentDOS);
            }
            if(CollectionUtil.isNotEmpty(pulishDetails)){
                dto.setPulishDetails(pulishDetails);
            }
            detailsDTOS.add(dto);
        }
        return detailsDTOS;
    }

    private String transFxdj(int fxdj){
        if(fxdj == 1){
            return "一般风险";
        }else if(fxdj == 2){
            return "中风险";
        }else if(fxdj == 3){
            return "高风险";
        }else{
            return "";
        }
    }

    @Override
    public List<TaskMedcClueFeedbackStatisticDTO> getFeedbackStatisticByRegion(String host, Integer port,String pwd, LoginUserDTO loginUserDTO,String region, String taskCode){
        String userRegion = loginUserDTO.getRegion();
        UserCategoryEnums enums = UserRegionUtils.getUserCateEnumByAscm(userRegion);
        List<TTask> pTaskList = tTaskMapper.selectRootTaskByBelongToAndTaskCode(enums.name(), taskCode);
        List<TaskMedcClueFeedbackStatisticDTO> result = Lists.newArrayList();
        List<TaskMedcClueFeedbackStatisticDTO> dataList = Lists.newArrayList();
        String tableName = tTaskSqlExecuteMapper.getTableNameByTaskId(taskCode);
        if(enums == UserCategoryEnums.GLOBAL && StringUtils.isEmpty(region)){
             List<RegionDO> regionDOS = regionService.getRegionsBypRegion("999");
             String countSql = "select count(distinct fixmedins_code) total,fx_level fxdj,concat(provice_code,'0000') subject from "+tableName+" where provice_code is not null group by provice_code,fxdj order by provice_code,fxdj";
            //TO-DO:本地sql
            //String countSql = "select count(distinct hosp_code) total,fx_level fxdj,concat(substring(provice_code,1,2),'0000') subject from "+tableName+" where provice_code is not null group by provice_code,fxdj";
             List<Map<String, Object>> countData = dataFluxService.getTaskSqlExecuteList(host, port,pwd, countSql);
            if(CollectionUtil.isNotEmpty(countData)){
                List<TaskMedcClueFeedbackStatisticDTO> list = transformClueMap(countData);
                List<TaskMedcClueFeedbackStatisticBasicDTO> medcDtos = tTaskMedcClueFeedbackMapper.statisticFeedbackMedcWithGlobal(taskCode);
                List<TaskMedcClueFeedbackStatisticBasicDTO> dtos = tTaskMedcClueFeedbackMapper.statisticFeedbackWithGlobal(taskCode);
                 if(CollectionUtil.isNotEmpty(dtos)){
                     String title = pTaskList.get(0).getTitle();
                     fixFeedbackStatisticDTO(enums,taskCode,dtos,title,medcDtos,result,regionDOS);
                     dataList = matchFeedbackStatisticDTO(list,result,"999");

                 }
             }
        }else if(enums == UserCategoryEnums.GLOBAL && StringUtils.isNotEmpty(region)){
            enums = UserRegionUtils.getUserCateEnumByAscm(region);
            List<RegionDO> regionDOS = regionService.getRegionsBypRegion(region);
            String countSql = "select count(distinct fixmedins_code) total,fx_level fxdj,concat(city_code,'00') subject from "+tableName+" where provice_code = '"+region.substring(0,2)+"' and city_code is not null group by city_code,fxdj order by city_code,fxdj";
            //TO-DO:本地sql
            //String countSql = "select count(distinct hosp_code) total,fx_level fxdj,concat(substring(city_code,1,4),'00') subject from "+tableName+" where substring(provice_code,1,2) = '"+region.substring(0,2)+"' and city_code is not null group by city_code,fxdj";
            List<Map<String, Object>> countData = dataFluxService.getTaskSqlExecuteList(host,port,pwd, countSql);
            if(CollectionUtil.isNotEmpty(countData)){
                List<TaskMedcClueFeedbackStatisticDTO> list = transformClueMap(countData);
                List<TaskMedcClueFeedbackStatisticBasicDTO> medcDtos = tTaskMedcClueFeedbackMapper.statisticFeedbackMedcWithProvice(taskCode, region);
                List<TaskMedcClueFeedbackStatisticBasicDTO> dtos = tTaskMedcClueFeedbackMapper.statisticFeedbackWithProvice(taskCode,region);
                if(CollectionUtil.isNotEmpty(dtos)){
                    String finalRegion = region;
                    Optional<TTask> optional = pTaskList.stream().filter(e -> e.getPrv().equals(finalRegion)).findFirst();
                    String title = "";
                    if(optional.isPresent()){
                        title = optional.get().getTitle();
                    }else{
                        title = pTaskList.get(0).getTitle();
                    }
                    fixFeedbackStatisticDTO(enums,taskCode,dtos,title,medcDtos,result,regionDOS);
                    dataList = matchFeedbackStatisticDTO(list,result,region);
                }
            }
        }else if(enums == UserCategoryEnums.PROVINCE){
            List<RegionDO> regionDOS = regionService.getRegionsBypRegion(userRegion);
            if(StringUtils.isEmpty(region)){
                region = userRegion;
            }
            String countSql = "select count(distinct fixmedins_code) total,fx_level fxdj,concat(city_code,'00') subject from "+tableName+" where provice_code = '"+region.substring(0,2)+"' and city_code is not null group by city_code,fxdj order by city_code,fxdj";
            //TO-DO:本地sql
           //String countSql = "select count(distinct hosp_code) total,fx_level fxdj,concat(substring(city_code,1,4),'00') subject from "+tableName+" where substring(provice_code,1,2) = '"+region.substring(0,2)+"' and city_code is not null group by city_code,fxdj";
             List<Map<String, Object>> countData = dataFluxService.getTaskSqlExecuteList(host,port,pwd, countSql);
            if(CollectionUtil.isNotEmpty(countData)){
                 List<TaskMedcClueFeedbackStatisticDTO> list = transformClueMap(countData);
                List<TaskMedcClueFeedbackStatisticBasicDTO> medcDtos = tTaskMedcClueFeedbackMapper.statisticFeedbackMedcWithProvice(taskCode, region);
                 List<TaskMedcClueFeedbackStatisticBasicDTO> dtos = tTaskMedcClueFeedbackMapper.statisticFeedbackWithProvice(taskCode,region);
                 if(CollectionUtil.isNotEmpty(dtos)){
                     Optional<TTask> optional = pTaskList.stream().filter(e -> e.getPrv().equals(userRegion)).findFirst();
                     String title = "";
                     if(optional.isPresent()){
                          title = optional.get().getTitle();
                     }else{
                          title = pTaskList.get(0).getTitle();
                     }
                     fixFeedbackStatisticDTO(enums,taskCode,dtos,title,medcDtos,result,regionDOS);
                     dataList = matchFeedbackStatisticDTO(list,result,region);
                 }
             }
        }
        return dataList;
    }

    public List<TaskMedcClueFeedbackStatisticDTO> matchFeedbackStatisticDTO(List<TaskMedcClueFeedbackStatisticDTO> list, List<TaskMedcClueFeedbackStatisticDTO> dtos,String pRegion) {
        List<TaskMedcClueFeedbackStatisticDTO> result = Lists.newArrayList();
        String taskName = dtos.get(0).getTaskName();
        List<RegionDO> regionDOS = regionService.getRegionsBypRegion(pRegion);
        for (TaskMedcClueFeedbackStatisticDTO basicDTO:list) {
            TaskMedcClueFeedbackStatisticDTO object = new TaskMedcClueFeedbackStatisticDTO();
            Optional<TaskMedcClueFeedbackStatisticDTO> optional = dtos.stream().filter(r -> r.getSubjectCode().equals(basicDTO.getSubjectCode())&& r.getFxdj().intValue()==basicDTO.getFxdj().intValue()).findFirst();
            if(optional.isPresent()){
                TaskMedcClueFeedbackStatisticBasicDTO source = optional.get();
                BeanUtils.copyProperties(source, object);
                object.setTotalNumber(basicDTO.getTotalNumber());
            }else {
                object = basicDTO;
                object.setTaskName(taskName);
                Optional<RegionDO> op = regionDOS.stream().filter(re -> basicDTO.getSubjectCode().equals(String.valueOf(re.getRegion()))).findFirst();
                if(op.isPresent()){
                    RegionDO fliterData = op.get();
                    if(pRegion.equals("999")){
                        object.setSubjectName(fliterData.getProvice());
                    }else{
                        object.setSubjectName(fliterData.getCity());
                    }
                }else{
                    object.setSubjectName(pRegion);
                }
                object.setDualNumber(0);
            }
            result.add(object);
        }
        return result;
    }

    public void fixFeedbackStatisticDTO(UserCategoryEnums enums,String taskCode,List<TaskMedcClueFeedbackStatisticBasicDTO> dtos,String title,List<TaskMedcClueFeedbackStatisticBasicDTO> medcDtos,List<TaskMedcClueFeedbackStatisticDTO> result,List<RegionDO> regionDOS){
        Map<String, Map<Integer, List<TaskMedcClueFeedbackStatisticBasicDTO>>> maps = dtos.stream().collect(Collectors.groupingBy(TaskMedcClueFeedbackStatisticBasicDTO::getSubjectCode,Collectors.groupingBy(TaskMedcClueFeedbackStatisticBasicDTO::getFxdj)));
        for (Map.Entry<String,Map<Integer, List<TaskMedcClueFeedbackStatisticBasicDTO>>> ent1: maps.entrySet()) {
            String regionCode = ent1.getKey();
            Map<Integer, List<TaskMedcClueFeedbackStatisticBasicDTO>> mp = ent1.getValue();
            for (Map.Entry<Integer,List<TaskMedcClueFeedbackStatisticBasicDTO>> entry: mp.entrySet()) {
                TaskMedcClueFeedbackStatisticDTO dto = new TaskMedcClueFeedbackStatisticDTO();
                List<TaskMedcClueFeedbackStatisticBasicDTO> ls = entry.getValue();
                dto.setFxdj(entry.getKey());
                dto.setTaskCode(taskCode);
                dto.setTaskName(title);
                dto.setSubjectCode(regionCode);
                Optional<RegionDO> optional = regionDOS.stream().filter(re -> regionCode.equals(String.valueOf(re.getRegion()))).findFirst();
                if(optional.isPresent()){
                    RegionDO fliterData = optional.get();
                    if(enums == UserCategoryEnums.GLOBAL){
                        dto.setSubjectName(fliterData.getProvice());
                    }else if(enums == UserCategoryEnums.PROVINCE){
                        dto.setSubjectName(fliterData.getCity());
                    }else{
                        dto.setSubjectName(fliterData.getDistrinct());
                    }
                }else{
                    dto.setSubjectName(regionCode);
                }
                Optional<TaskMedcClueFeedbackStatisticBasicDTO> optional2 = medcDtos.stream().filter( e-> e.getFxdj().intValue()==dto.getFxdj().intValue() && e.getSubjectCode().equals(regionCode)).findFirst();
                if(optional2.isPresent()){
                    TaskMedcClueFeedbackStatisticBasicDTO medcFeedback = optional2.get();
                    dto.setDualNumber(medcFeedback.getCheckResultNumber());
                }else{
                    dto.setDualNumber(0);
                }
                fixFeedbackStatisticNumbers(dto, ls);
                result.add(dto);
            }
        }
    }

    private void fixFeedbackStatisticNumbers(TaskMedcClueFeedbackStatisticDTO dto, List<TaskMedcClueFeedbackStatisticBasicDTO> ls) {
        int sendGANumber = 0;
        int sendWJNumber = 0;
        int numTotal = 0;
        BigDecimal violateTotal = new BigDecimal(0);
        BigDecimal violateFundTotal = new BigDecimal(0);
        BigDecimal violateFinanceTotal = new BigDecimal(0);
        BigDecimal pulishTotal = new BigDecimal(0);
        BigDecimal penaltyCost = new BigDecimal(0);
        for (TaskMedcClueFeedbackStatisticBasicDTO basicDTO:ls) {
            violateTotal = violateTotal.add(basicDTO.getViolateCost()==null?new BigDecimal(0):basicDTO.getViolateCost()).setScale(2,BigDecimal.ROUND_HALF_UP);
            violateFundTotal = violateFundTotal.add(basicDTO.getViolateFund()==null?new BigDecimal(0):basicDTO.getViolateFund()).setScale(2,BigDecimal.ROUND_HALF_UP);
            violateFinanceTotal = violateFinanceTotal.add(basicDTO.getViolateFinance()==null?new BigDecimal(0):basicDTO.getViolateFinance()).setScale(2,BigDecimal.ROUND_HALF_UP);
            pulishTotal = pulishTotal.add(basicDTO.getPulishCost()==null?new BigDecimal(0):basicDTO.getPulishCost()).setScale(2,BigDecimal.ROUND_HALF_UP);
            penaltyCost = penaltyCost.add(basicDTO.getPenaltyCost()==null?new BigDecimal(0):basicDTO.getPenaltyCost()).setScale(2,BigDecimal.ROUND_HALF_UP);
            numTotal += basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber();
            if(basicDTO.getCheckResult().intValue() == CheckResultEnums.INTERVIEW.getValue().intValue()){
                dto.setInterviewCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.NOTICE_CRITICISM.getValue().intValue()){
                dto.setNoticeCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.DEADLINE_RECTIFICATION.getValue().intValue()){
                dto.setRectificateCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.STOP_AGREE.getValue().intValue()){
                dto.setStopAgreeCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.RELEASE_AGREE.getValue().intValue()){
                dto.setReleaseAgreeCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.SEND_GA.getValue().intValue()){
                Integer sendGACount = basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber();
                dto.setSendGACount(dto.getSendGACount()==null?0+sendGACount:dto.getSendGACount()+sendGACount);
                sendGANumber +=basicDTO.getSendByNumber()==null?0:basicDTO.getSendByNumber();
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.SEND_SF.getValue().intValue()){
                Integer sendGACount = basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber();
                dto.setSendGACount(dto.getSendGACount()==null?0+sendGACount:dto.getSendGACount()+sendGACount);
                sendGANumber +=basicDTO.getSendByNumber()==null?0:basicDTO.getSendByNumber();
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.SEND_WJ.getValue().intValue()){
                dto.setSendWjCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
                sendWJNumber +=basicDTO.getSendByNumber()==null?0:basicDTO.getSendByNumber();
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.GOV_PULISHED.getValue().intValue()){
                dto.setPulishCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }else if(basicDTO.getCheckResult().intValue() == CheckResultEnums.NONE.getValue().intValue()){
                dto.setNoneCount(basicDTO.getCheckResultNumber()==null?0:basicDTO.getCheckResultNumber());
            }
        }
        dto.setNumSubTotal(numTotal);
        dto.setViolateCost(violateTotal);
        dto.setViolateFinance(violateFinanceTotal);
        dto.setViolateFund(violateFundTotal);
        dto.setPenaltyCost(penaltyCost);
        dto.setPulishCost(pulishTotal);
        dto.setSendGANumber(sendGANumber);
        dto.setSendWJNumber(sendWJNumber);
        dto.setPersonSubTotal(dto.getSendGANumber()+dto.getSendWJNumber());
        BigDecimal costTotal = dto.getPenaltyCost().add(dto.getPulishCost()).add(dto.getViolateCost()).setScale(2,BigDecimal.ROUND_HALF_UP);
        dto.setCostSubTotal(costTotal);
    }


    private List<TaskMedcClueFeedbackStatisticDTO> transformClueMap(List<Map<String, Object>> countData) {
        List<TaskMedcClueFeedbackStatisticDTO> result = Lists.newArrayList();
        countData.forEach(e -> {
            String region = String.valueOf(e.get("subject"));
            String fxdj = String.valueOf(e.get("fxdj"));
            String total = String.valueOf(e.get("total"));
            TaskMedcClueFeedbackStatisticDTO dto = new TaskMedcClueFeedbackStatisticDTO();
            dto.setSubjectCode(region);
            dto.setFxdj(Integer.valueOf(fxdj));
            dto.setTotalNumber(Integer.valueOf(total));
            result.add(dto);
        });
        return result;
    }
}




